package com.base.data.elasticsearch.repository.support;

import com.base.data.elasticsearch.core.mapping.BaseElasticsearchPersistentEntity;
import com.base.data.elasticsearch.core.mapping.BaseElasticsearchPersistentProperty;
import org.springframework.data.repository.core.support.PersistentEntityInformation;
import org.springframework.util.Assert;

public class BaseMappingElasticsearchEntityInformation<T, ID> extends PersistentEntityInformation<T, ID>
        implements BaseElasticsearchEntityInformation<T, ID> {

    private final BaseElasticsearchPersistentEntity<T> entityMetadata;
    private final String indexName;
    private final String type;

    public BaseMappingElasticsearchEntityInformation(BaseElasticsearchPersistentEntity<T> entity) {
        this(entity, entity.getIndexName(), entity.getIndexType());
    }

    public BaseMappingElasticsearchEntityInformation(BaseElasticsearchPersistentEntity<T> entity, String indexName, String type) {
        super(entity);

        Assert.notNull(indexName, "IndexName must not be null!");
        Assert.notNull(type, "IndexType must not be null!");

        this.entityMetadata = entity;
        this.indexName = indexName;
        this.type = type;
    }

    @Override
    public String getIdAttribute() {
        return entityMetadata.getRequiredIdProperty().getFieldName();
    }

    @Override
    public String getIndexName() {
        return indexName;
    }

    @Override
    public String getType() {
        return type;
    }

    @Override
    public Long getVersion(T entity) {

        BaseElasticsearchPersistentProperty versionProperty = entityMetadata.getVersionProperty();
        try {
            return versionProperty != null ? (Long) entityMetadata.getPropertyAccessor(entity).getProperty(versionProperty) : null;
        } catch (Exception e) {
            throw new IllegalStateException("failed to load version field", e);
        }
    }

    @Override
    public String getParentId(T entity) {

        BaseElasticsearchPersistentProperty parentProperty = entityMetadata.getParentIdProperty();
        try {
            return parentProperty != null ? (String) entityMetadata.getPropertyAccessor(entity).getProperty(parentProperty) : null;
        } catch (Exception e) {
            throw new IllegalStateException("failed to load parent ID: " + e, e);
        }
    }
}
